<template>
  <a-row :gutter="4">
    <a-col>
      <a-flex gap="small" justify="flex-end" class="ToolBar">
        <a-button @click="loadFieldDefine(props.model.id)" :title="$t('104')"
          >{{ $t("104") }}
        </a-button>
        <a-button
          v-if="!isRemoteStoreModel"
          type="primary"
          @click="goNewField"
          :disabled="state.editMode == 1"
          >{{ $t("312") }}</a-button
        >
        <a-button
          v-if="!isRemoteStoreModel"
          danger
          @click="removeField"
          :disabled="state.editMode != 2"
          :icon="h(DeleteOutlined)"
          :title="$t('313')"
        />
        <a-button v-if="isRemoteStoreModel" @click="reImportFiled"
          >重新导入
        </a-button>
      </a-flex>
      <a-table
        :columns="colField"
        :data-source="lstField"
        bordered
        size="small"
        :row-selection="rowSelection"
        :pagination="false"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex == 'displayOrder'">
            <template v-if="record.multi">
              <span>{{ record.displayOrder }} +</span>
            </template>
          </template>
          <template v-if="column.dataIndex == 'label'">
            <template v-if="record.required">
              <span style="color: blue">{{ record.label }}</span>
            </template>
            <template v-else>
              {{ record.label }}
            </template>
          </template>
        </template>
      </a-table>
    </a-col>
    <a-col>
      <a-form
        size="small"
        layout="vertical"
        :model="form"
        :disabled="state.editMode != 2 && state.editMode != 1"
        style="margin: 4px"
      >
        <a-form-item :label="$t('315')" required>
          <a-input v-model:value="form.label" />
        </a-form-item>
        <a-form-item :label="$t('316')" required>
          <a-select v-model:value="form.fieldType" @change="onFieldTypeChange">
            <a-select-option
              v-for="item in appStore.aryFieldType"
              :key="item.code"
              :value="item.code"
              >{{ item.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :label="$t('317')" required>
          <a-input-number
            v-model:value="form.displayOrder"
            :min="1"
            :max="80"
          />
        </a-form-item>
        <div v-if="!CommonDefine.useful(props.model.store)">
          <a-form-item :label="$t('318')">
            <a-switch v-model:checked="form.required" />
          </a-form-item>
          <a-form-item :label="$t('434')">
            <a-switch v-model:checked="form.unique" />
          </a-form-item>
          <a-form-item :help="$t('320')" :label="$t('319')">
            <a-switch v-model:checked="form.multi" />
          </a-form-item>
          <a-form-item :label="$t('321')">
            <a-textarea v-model:value="form.inputHint" auto-size />
          </a-form-item>
          <div v-if="form.fieldType > 100 && form.fieldType < 200">
            <a-form-item
              v-if="form.fieldType == 101"
              :help="$t('323')"
              :label="$t('322')"
            >
              <a-input-number
                v-model:value="form.minLen"
                :min="0"
              ></a-input-number>
            </a-form-item>
            <a-form-item :help="$t('323')" :label="$t('324')">
              <a-input-number
                v-model:value="form.maxLen"
                :min="0"
              ></a-input-number>
            </a-form-item>
            <a-form-item :label="$t('326')" v-if="form.fieldType == 101">
              <a-select v-model:value="form.pattern">
                <a-select-option value="0">{{ $t("327") }}</a-select-option>
                <a-select-option value="1">{{ $t("328") }}</a-select-option>
                <a-select-option value="2">{{ $t("329") }}</a-select-option>
                <a-select-option value="3">{{ $t("330") }}</a-select-option>
              </a-select>
            </a-form-item>
          </div>
          <div v-if="form.fieldType > 200 && form.fieldType < 211">
            <a-form-item :help="$t('332')" :label="$t('331')">
              <a-input-number v-model:value="form.minV"></a-input-number>
            </a-form-item>
            <a-form-item :help="$t('332')" :label="$t('333')">
              <a-input-number v-model:value="form.maxV"></a-input-number>
            </a-form-item>
            <a-form-item v-if="form.fieldType == 202" :label="$t('334')">
              <a-input-number
                v-model:value="form.decimalCount"
                :max="10"
                :min="0"
              ></a-input-number>
            </a-form-item>
            <a-form-item :label="$t('335')">
              <a-input v-model:value="form.unitLabel" />
            </a-form-item>
          </div>
          <div v-if="form.fieldType == 212">
            <a-form-item label="起始值">
              <a-input-number v-model:value="form.start"></a-input-number>
            </a-form-item>
            <a-form-item label="步进">
              <a-input-number v-model:value="form.step"></a-input-number>
            </a-form-item>
            <a-form-item label="极限值">
              <a-input-number v-model:value="form.limit"></a-input-number>
            </a-form-item>
          </div>
          <div v-if="form.fieldType > 300 && form.fieldType < 400">
            <a-form-item :label="$t('336')">
              <a-select v-model:value="form.format">
                <a-select-option value="0">YYYY-MM-DD hh:mm:ss</a-select-option>
                <a-select-option value="1">YYYY.M.D</a-select-option>
                <a-select-option value="11">YYYY.MM.DD</a-select-option>
                <a-select-option value="33">YYYY年M月D日</a-select-option>
              </a-select>
            </a-form-item>
          </div>
          <div v-if="form.fileTpe == 401">
            <a-form-item label="最大(MB)">
              <a-input-number
                v-model:value="form.maxMB"
                :min="1"
                :max="256"
              ></a-input-number>
            </a-form-item>
          </div>
          <div v-if="form.fieldType == 501">
            <a-form-item :label="$t('337')">
              <a-select v-model:value="form.action">
                <a-select-option
                  v-for="item in appStore.aryComputAction"
                  :key="item.key"
                  :value="item.key"
                  >{{ item.label }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item v-if="form.action == 12" :label="$t('338')">
              <a-select v-model:value="form.lmId" @change="onLinkModelChange">
                <a-select-option
                  v-for="item in lstModel"
                  :key="item.key"
                  :value="item.model.id"
                  >{{ item.model.name }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item v-if="form.action == 12" :label="$t('339')">
              <a-select v-model:value="form.lfId">
                <a-select-option
                  v-for="item in fieldsOfLinkedModel"
                  :key="item.id"
                  :value="item.id"
                  >{{ item.label }} <br /><small>{{
                    appStore.aryFieldType
                      .find((ft) => ft.key == item.fieldType.T)
                      .map((ft) => ft.label)
                  }}</small>
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item
              v-if="form.action > 20 && form.action < 30"
              label="参与字段"
            >
              <FieldSelector
                ref="refFieldSelector"
                :modelId="props.model.id"
                :multi="true"
                :return-tag="false"
                @ok="onFieldSelected"
              />
            </a-form-item>
            <a-form-item
              v-if="form.action == 23 || form.action == 24"
              label="计算结果保留小数位数"
            >
              <a-input-number
                v-model:value="form.digits"
                :max="10"
                :min="0"
              ></a-input-number>
            </a-form-item>
          </div>
          <div v-if="form.fieldType == 801">
            <CodeSource ref="refCSE" @change="onCodeSourceChange"></CodeSource>
          </div>
          <div v-if="form.fieldType == 901 || form.fieldType == 903">
            <a-form-item
              :label="$t('338')"
              required
              v-if="form.fieldType == 901"
            >
              <a-select v-model:value="form.lmId" @change="onLinkModelChange">
                <a-select-option
                  v-for="item in lstModel"
                  :key="item.model.id"
                  :value="item.model.id"
                  >{{ item.model.name }} <br /><small>{{
                    item.model.memo
                  }}</small>
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item :label="$t('339')" required>
              <a-select v-model:value="form.lfId">
                <a-select-option
                  v-for="item in fieldsOfLinkedModel"
                  :key="item.id"
                  :value="item.id"
                  >{{ item.label }} <br /><small>{{
                    appStore.aryFieldType
                      .find((ft) => ft.key == item.fieldType)
                      .map((ft) => ft.label)
                  }}</small>
                </a-select-option>
              </a-select>
            </a-form-item>
          </div>
        </div>
        <a-form-item>
          <a-button
            type="primary"
            :disabled="state.editMode == 0"
            @click="doSaveField"
            >{{ $t("224") }}</a-button
          ></a-form-item
        >
      </a-form>
    </a-col>
  </a-row>
</template>
<script setup>
import { computed, h, nextTick, reactive, ref, watch } from "vue";
import CommonDefine from "@/component/CommonDefine";
import CodeSource from "@/my/FieldCodeSource.vue";
import FieldSelector from "@/component/field/FieldSelector.vue";
import { DeleteOutlined } from "@ant-design/icons-vue";
import { useI18n } from "vue-i18n";

const props = defineProps({
  model: { type: Object, default: () => {} },
});
const { t } = useI18n();
const appStore = CommonDefine.appStore();
const colField = [
  { title: t("317"), dataIndex: "displayOrder" },
  { title: t("315"), dataIndex: "label" },
  { title: t("316"), dataIndex: "fieldTypeLabel" },
];
const state = reactive({
  editMode: 0, // 0查看 1新建 2修改
  popTagTree: false,
  currentField: {},
});
const form = reactive({});
const fieldsOfLinkedModel = ref([]);
const lstField = reactive([]);
const isRemoteStoreModel = computed(() =>
  CommonDefine.useful(props.model.store)
);

const onLinkModelChange = (e) => {
  CommonDefine.clearArray(fieldsOfLinkedModel.value);
  CommonDefine.runWithFieldCache(e, (fields) => {
    fields.forEach((fd) => {
      // 字段不能被外部链接
      if (
        fd.fieldType == 501 ||
        fd.fieldType == 901 ||
        fd.fieldType == 911 ||
        fd.fieldType == 903 ||
        fd.fieldType == 912
      ) {
        return;
      }
      fd.key = fd.id;
      fieldsOfLinkedModel.value.push(fd);
    });
  });
};

const onFieldTypeChange = () => {
  if (form.fieldType == 903) {
    CommonDefine.clearArray(fieldsOfLinkedModel.value);
    lstField.forEach((fd) => {
      // 字段不能被外部链接
      if (
        fd.fieldType == 501 ||
        fd.fieldType == 901 ||
        fd.fieldType == 911 ||
        fd.fieldType == 903 ||
        fd.fieldType == 912
      ) {
        return;
      }
      fd.key = fd.id;
      fieldsOfLinkedModel.value.push(fd);
    });
  }
};

const onCodeSourceChange = (event) => {
  // console.log(event);
  form.codeSource = JSON.stringify(event);
};

const rowSelection = ref({
  type: "radio",
  hideSelectAll: true,
  onChange: (selectedRowKeys, selectedRows) => {
    if (selectedRowKeys.length > 0) {
      state.editMode = 2;
      setFormView(selectedRowKeys[0]);
    }
  },
});

const lstModel = computed(() => {
  let allModelAry = appStore.allMyModels;
  return allModelAry.filter((m) => m.model.id != props.model.id);
});

const setFormView = (recordKey) => {
  let field = lstField.find((fd) => {
    return fd.id == recordKey;
  });
  state.currentField = field;
  state.editMode = 2;
  Object.assign(form, field);
  form.fieldType = appStore.aryFieldType.find(
    (x) => x.key == field.fieldType.T
  ).code;
  if (form.fieldType == 501) {
    form.command = field.fieldType.C;
  } else if (form.fieldType == 801) {
    form.codeSource = field.fieldType.C;
    nextTick(() => {
      refCSE.value.setCodeSource(field.fieldType.C);
    });
  } else {
    Object.assign(form, field.fieldType.C);
  }
};

const loadFieldDefine = (modelId) => {
  state.editMode = 0;
  let fn = (fields) => {
    lstField.splice(0, lstField.length);
    fields.forEach((x) => {
      x.key = x.id;
      x.fieldTypeLabel = appStore.aryFieldType.find(
        (y) => y.key == x.fieldType.T
      ).label;
      lstField.push(x);
    });
    loadTagTree(modelId);
  };
  // 不能用缓存，要强制从后台获取最新数据
  CommonDefine.apiGetArm(`/api/v1/model/list-field/${modelId}`, (d) => {
    appStore.allModelFieldMap.set(modelId, d);
    fn(d);
  });
};

const goNewField = () => {
  CommonDefine.clearProperty(form);
  form.displayOrder = lstField.length + 1;
  form.modelId = props.model.id;
  form.required = false;
  form.multi = false;
  state.editMode = 1;
};

const refCSE = ref();

// 保存字段定义
const doSaveField = () => {
  form.modelId = props.model.id;
  delete form["key"];
  delete form["fieldTypeLabel"];
  delete form["rule"];
  // 智能计算字段的提交值处理
  if (form.fieldType == 501) {
    if (form.action == 12) {
      let args = [];
      if (form.lmId) {
        args.push(form.lmId.toString());
        delete form["lmId"];
      }
      if (form.lfId) {
        args.push(form.lfId.toString());
        delete form["lfId"];
      }
      form.args = args;
    }
  }
  switch (state.editMode) {
    case 1:
      CommonDefine.apiPostArm("/api/v1/model/create-field", form, (d) => {
        loadFieldDefine(props.model.id);
        state.editMode = 0;
        CommonDefine.alert(t("340"));
      });
      break;
    case 2:
      form.fieldId = state.currentField.id;
      CommonDefine.apiPostArm("/api/v1/model/change-field", form, (d) => {
        loadFieldDefine(props.model.id);
        state.editMode = 0;
        CommonDefine.alert(t("341"));
      });
      break;
  }
};

const removeField = () => {
  CommonDefine.apiPostArm(
    `/api/v1/model/remove-field/${state.currentField.id}`,
    null,
    (d) => {
      loadFieldDefine(props.model.id);
      state.editMode = 0;
    }
  );
};

const reImportFiled = () => {
  CommonDefine.apiPostArm(
    `/api/v1/model/re-import-field/${props.model.id}`,
    null,
    (d) => {
      CommonDefine.alert(t("342"));
      loadFieldDefine(props.model.id);
    }
  );
};

const lstTag = reactive([]);

const loadTagTree = (modelId) => {
  CommonDefine.clearArray(lstTag);
  CommonDefine.apiGetArm(
    `/api/v1/share/tags/` + modelId,
    (d) => {
      d.forEach((item) => {
        lstTag.push(item);
      });
    },
    false
  );
};

const onFieldSelected = (event) => {
  // console.log(event);
  form.args = event.map((x) => x.toString());
};

watch(
  () => props.model,
  (newValue) => {
    loadFieldDefine(newValue.id);
  },
  {
    immediate: true,
  }
);
</script>
